//=======================================================================//
//= Include files.													    =//
//=======================================================================//
#include <wx/settings.h>
#include "Rasterizer.h"

//=======================================================================//
//= Function define.										            =//
//=======================================================================//
ImageRasterizer::ImageRasterizer(const wxSize& clsSize)
: wxMemoryDC()
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	/* Create a bitmap for buffer, color depth set to 1. */
	m_clsPaintBuffer.Create(clsSize, 1);
	wxMemoryDC::SelectObject(m_clsPaintBuffer);
}

ImageRasterizer::ImageRasterizer(const ImageRasterizer& clsSource)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	m_clsPaintBuffer = clsSource.AsBitmap();
}

ImageRasterizer::~ImageRasterizer(void)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	/* Copy pixelated image. */
	wxMemoryDC::SelectObject(wxNullBitmap);
	/* m_clsPaintPen only used when set pixel, no need to copy. */
	// m_clsPaintPen
}

void ImageRasterizer::SetPixel(int iPosX, int iPosY, int iValue)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	if(1 == iValue)
	{
		m_clsPaintPen.SetColour(*wxBLACK);
	}
	else
	{
		m_clsPaintPen.SetColour(*wxWHITE);
	}
	SetPen(m_clsPaintPen);
	DrawPoint(iPosX, iPosY);
}

int ImageRasterizer::GetPixel(int iPosX, int iPosY) const
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
    int						iPixelValue;
    wxColour				clsPixelColour;

    /*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
    if((iPosX < m_clsPaintBuffer.GetWidth()) && (iPosY < m_clsPaintBuffer.GetHeight()))
	{
		iPixelValue = wxMemoryDC::GetPixel(iPosX, iPosY, &clsPixelColour);
		if((*wxBLACK) == clsPixelColour)
		{
			iPixelValue = 1;
		}
		else
		{
			iPixelValue = 0;
		}
	}
	else
	{
		iPixelValue = 0;
	}
	return iPixelValue;
}

void ImageRasterizer::ResizePaintBuffer(const wxSize& clsNewSize)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	// Recreate bitmap for new size(Since wxWidgets 3.1.2)
	m_clsPaintBuffer.Create(clsNewSize, 1);
	wxMemoryDC::SelectObject(m_clsPaintBuffer);
}

void ImageRasterizer::CleanPaintBuffer(void)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	wxMemoryDC::SetPen(*wxWHITE);
	wxMemoryDC::SetBrush(*wxWHITE);
	wxMemoryDC::DrawRectangle(0, 0, GetWidth(), GetHeight());
}

void ImageRasterizer::DestroyPaintBuffer(void)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	m_clsPaintBuffer = wxNullBitmap;
}


CharacterRasterizer::CharacterRasterizer(void)
: ImageRasterizer()
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	/* Load system default font. */
	wxMemoryDC::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
}

CharacterRasterizer::~CharacterRasterizer(void)
{

}

void CharacterRasterizer::SetFont(const FontSettings& clsFont)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	m_clsFont = clsFont;
	wxMemoryDC::SetFont(m_clsFont.Font());
}

void CharacterRasterizer::Convert(const wxChar& iCode)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	wxSize				clsCharSize;
	int					iCharWidth;
	int                 iCharPosX = 0;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	m_wcCharCode = iCode;
	clsCharSize = wxMemoryDC::GetTextExtent(wxString(iCode));


	if((clsCharSize.GetWidth() > 0) && (clsCharSize.GetHeight() > 0))
	{
		// Force fix width.
		if((m_clsFont.GetForcedWidthValue() > 0) && (m_clsFont.IsForceWidth()))
		{
			//if(iCode > 127)
			if(wxIsascii(iCode))
			{
				iCharWidth = m_clsFont.GetForcedWidthValue();
			}
			else
			{
				iCharWidth = m_clsFont.GetForcedWidthValue()*2;
			}
			iCharPosX = (iCharWidth - clsCharSize.GetWidth()) / 2;
			clsCharSize.SetWidth(iCharWidth);
		}
		// update height.
		clsCharSize.SetHeight(m_clsFont.GetHeight());
		ResizePaintBuffer(clsCharSize);
		wxMemoryDC::SetTextBackground(*wxWHITE);
		wxMemoryDC::SetTextForeground(*wxBLACK);
		CleanPaintBuffer();
		wxMemoryDC::DrawText(wxString(iCode), wxPoint(m_clsFont.GetOffsetX()+iCharPosX, m_clsFont.GetOffsetY()));
	}
	else
	{
		DestroyPaintBuffer();
	}
}
